﻿using System;
using EzDesk.Apps.ServiceImpl.Attendance.Evaluation;
using NUnit.Framework;

namespace EzDesk.Apps.UnitTest.Attendance
{
    /// <summary>
    /// 计算迟到和早退的时间
    /// </summary>
    [TestFixture]
    public class SimpleDayAttendanceEvaluationLateAndEarlyFixture
    {

        private void assertLateAndEarly(LateAndEarlyMins actualResult, int lateMiniutes, int earlyMiniutes)
        {
            Assert.AreEqual(actualResult.EarlyMiniutes, earlyMiniutes);
            Assert.AreEqual(actualResult.LateMiniutes, lateMiniutes);
        }

        #region 当日考勤的情况

        [Test]
        public void Test_正常情况()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")
                .SetupAttendanceInfo("9:40", "onDuty", false)
                .SetupAttendanceInfo("19:00", "offDuty", false) as DayAttendanceEvaluationContext;
            
            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 40, 0);
        }


        [Test]
        public void Test_早上迟到下午没加班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("10:20", "onDuty", false)
                .SetupAttendanceInfo("19:00", "offDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 80, 0);
        }

        [Test]
        public void Test_早上迟到下午加班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("11:20", "onDuty", false)
                .SetupAttendanceInfo("20:50", "offDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 140, 0);
        }


        [Test]
        public void Test_早上正常上班下午早退()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("8:50", "onDuty", false)
                .SetupAttendanceInfo("16:40", "offDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 0, 70);
        }


        [Test]
        public void Test_早上正常上班下午没打卡()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("8:50", "onDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 0, 0);
        }


        [Test]
        public void Test_早上迟到下午没打卡()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("10:50", "onDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 110, 0);
        }


        [Test]
        public void Test_早上没打卡下午打了下班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("19:50", "offDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 0, 0);
        }


        [Test]
        public void Test_中午过来上班晚上正常下班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("12:10", "onDuty", true)
                .SetupAttendanceInfo("19:10", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 190, 0);
        }


        [Test]
        public void Test_下午过来上班晚上提前下班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("15:50", "onDuty", true)
                .SetupAttendanceInfo("18:50", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 410, 0);
        }


        [Test]
        public void Test_昨晚通宵到今天正常上班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("2:20", "offDuty", true)
                .SetupAttendanceInfo("10:00", "onDuty", false)
                .SetupAttendanceInfo("19:00", "offDuty", false)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.Service.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 60, 0);
        }

        [Test]
        public void Test_昨晚通宵到今天早上下班_下午过来上班晚上下班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("3:20", "offDuty", true)
                .SetupAttendanceInfo("14:00", "onDuty", true)
                .SetupAttendanceInfo("20:50", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 300, 0);
        }

        [Test]
        public void Test_连续几次非正常上下班_按最少的计算()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-12")

                .SetupAttendanceInfo("3:20", "onDuty", true)  // 有效
                .SetupAttendanceInfo("4:20", "onDuty", true)
                .SetupAttendanceInfo("5:20", "onDuty", true)
                .SetupAttendanceInfo("7:20", "offDuty", true)  // 有效
                .SetupAttendanceInfo("8:20", "offDuty", true)


                .SetupAttendanceInfo("17:20", "onDuty", true)
                .SetupAttendanceInfo("20:20", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateManhours();

            Assert.AreEqual(actualResult, 420);
        }

        #endregion



        #region 跨天考勤的情况

        [Test]
        public void Test_通宵加班_到第二天凌晨上班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-11")
                .SetCurrentDay("2010-11-11")
                .SetupAttendanceInfo("9:00", "onDuty", true)
                .SetupAttendanceInfo("15:00", "offDuty", true)
                .SetupAttendanceInfo("20:00", "onDuty", true)

                .SetCurrentDay("2010-11-12")
                .SetupAttendanceInfo("2:00", "offDuty", true)

                .SetupAttendanceInfo("11:30", "onDuty", true)
                .SetupAttendanceInfo("20:00", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 0, 180);

        }

        [Test]
        public void Test_忘了下班打卡_第二天正常上班()
        {
            var context = new DayAttendanceEvaluationContext()
                .SetupDay("2010-11-11")
                .SetCurrentDay("2010-11-11")
                .SetupAttendanceInfo("9:00", "onDuty", true)

                .SetCurrentDay("2010-11-12")
                .SetupAttendanceInfo("9:00", "onDuty", true)

                .SetupAttendanceInfo("18:30", "offDuty", true)
                 as DayAttendanceEvaluationContext;

            var actualResult = context.SimpleService.CalculateLateAndEarlyMinutes();

            assertLateAndEarly(actualResult, 0, 0);

        }

        #endregion
    }
}